package com.spider.spiderorderadmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spider.spiderorderadmin.entity.dto.ResourceTreeNode;
import com.spider.spiderorderadmin.entity.dto.SystemResourceDTO;
import com.spider.spiderorderadmin.entity.enums.DataDictionaryEnum;
import com.spider.spiderorderadmin.entity.model.SystemResource;
import com.spider.spiderorderadmin.entity.param.SystemResourceQueryParam;
import com.spider.spiderorderadmin.exception.BusinessException;
import com.spider.spiderorderadmin.exception.ExceptionDef;
import com.spider.spiderorderadmin.mapper.SystemResourceMapper;
import com.spider.spiderorderadmin.service.SystemResourceService;
import com.spider.spiderorderadmin.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xiong.bo
 * @version 1.0
 * @date 2020/11/29 12:37
 */
@Service("systemResourceService")
public class SystemResourceServiceImpl extends ServiceImpl<SystemResourceMapper, SystemResource> implements SystemResourceService {


    @Override
    public Page<SystemResource> selectPage(SystemResourceQueryParam queryParam) {
        LambdaQueryWrapper<SystemResource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(queryParam.getType()), SystemResource::getType, queryParam.getType());
        queryWrapper.like(StringUtils.hasText(queryParam.getCode()), SystemResource::getCode, queryParam.getCode());
        queryWrapper.like(StringUtils.hasText(queryParam.getName()), SystemResource::getName, queryParam.getName());
        queryWrapper.orderByDesc(SystemResource::getCreateTime);
        return this.baseMapper.selectPage(queryParam.buildPage(), queryWrapper);
    }

    @Override
    public List<ResourceTreeNode> selectTreeResource() {

        //将数据一次性查询出来，再通过递归转换数据
        LambdaQueryWrapper<SystemResource> queryWrapper = new LambdaQueryWrapper<>();
        List<SystemResource> allResourceList = this.baseMapper.selectList(queryWrapper);

        // 实体类转换为树形结构类
        List<ResourceTreeNode> treeNodeList = new ArrayList<>();
        for (SystemResource resource : allResourceList){
            ResourceTreeNode resourceNode = new ResourceTreeNode();
            BeanUtils.copyProperties(resource, resourceNode);
            resourceNode.setKey(resourceNode.getId());
            treeNodeList.add(resourceNode);
        }

        // 初始化一个空的根节点列表（通常用于没有父级的节点）
        List<ResourceTreeNode> result = new ArrayList<>();

        // 遍历所有分类，构建树形结构
        for (ResourceTreeNode resourceNode : treeNodeList) {
            if (resourceNode.getParentId() == null) {
                // 如果没有父级，则它是根节点
                result.add(resourceNode);
            } else {
                // 否则，找到它的父节点并添加到子列表中
                addResourceToParent(treeNodeList, resourceNode);
            }
        }

        return result;
    }

    // 递归方法，将子分类添加到其父分类的子列表中
    private void addResourceToParent(List<ResourceTreeNode> allCategories, ResourceTreeNode resourceNode) {
        for (ResourceTreeNode parentNode : allCategories) {
            if (parentNode.getId().equals(resourceNode.getParentId())) {
                if (parentNode.getChildren() == null) {
                    parentNode.setChildren(new ArrayList<>());
                }
                parentNode.getChildren().add(resourceNode);
                // 如果Resource还有子分类，递归处理
                for (ResourceTreeNode subNode : allCategories) {
                    if (subNode.getParentId() != null
                            && subNode.getParentId().equals(resourceNode.getId())) {
                        addResourceToParent(allCategories, subNode);
                    }
                }
                break; // 找到父节点后退出循环
            }
        }
    }


    @Override
    public SystemResource findById(Long id) {
        SystemResource systemResource = this.baseMapper.selectById(id);
        if (systemResource == null) {
            throw new BusinessException(ExceptionDef.ERROR_DATA_NOT_EXIST);
        }
        return systemResource;
    }

    @Override
    public SystemResource save(SystemResourceDTO systemResourceDTO, Long userId) {

        if (systemResourceDTO.getParentId() == null && !DataDictionaryEnum.MENU.getCode().equals(systemResourceDTO.getType())){
            throw new BusinessException("顶级资源只能是菜单类型");
        }

        SystemResource resourceData = new SystemResource();
        resourceData.setParentId(systemResourceDTO.getParentId());
        resourceData.setName(systemResourceDTO.getName());
        resourceData.setCode(systemResourceDTO.getCode());
        resourceData.setType(systemResourceDTO.getType());
        resourceData.setShowOrder(systemResourceDTO.getShowOrder());
        resourceData.setRemark(systemResourceDTO.getRemark());
        resourceData.setResUrl(systemResourceDTO.getResUrl());
        int s = DataDictionaryEnum.ENABLE.getCode().equals(systemResourceDTO.getDataStatus()) ? DataDictionaryEnum.ENABLE.getCode()
                : DataDictionaryEnum.DISABLE.getCode();
        resourceData.setDataStatus(s);
        resourceData.setCreateTime(DateUtils.getCurrentTimestamp());
        resourceData.setCreateUser(userId);
        this.baseMapper.insert(resourceData);

        return resourceData;
    }

    @Override
    public SystemResource update(SystemResourceDTO systemResourceDTO, Long userId) {

        SystemResource existsResource = findById(systemResourceDTO.getId());

        existsResource.setName(systemResourceDTO.getName());
        existsResource.setCode(systemResourceDTO.getCode());
        existsResource.setType(systemResourceDTO.getType());
        existsResource.setShowOrder(systemResourceDTO.getShowOrder());
        int s = DataDictionaryEnum.ENABLE.getCode().equals(systemResourceDTO.getDataStatus()) ? DataDictionaryEnum.ENABLE.getCode()
                : DataDictionaryEnum.DISABLE.getCode();
        existsResource.setDataStatus(s);
        existsResource.setRemark(systemResourceDTO.getRemark());
        existsResource.setResUrl(systemResourceDTO.getResUrl());
        existsResource.setUpdateUser(userId);
        existsResource.setUpdateTime(DateUtils.getCurrentTimestamp());
        this.baseMapper.updateById(existsResource);

        return existsResource;
    }

    @Override
    public Boolean deleteByIds(String ids) {
        if (ids == null) {
            return true;
        }
        List<Long> idList = new ArrayList<>();
        if (ids.contains(",")) {
            String[] splitArray = ids.split(",");
            for (String str : splitArray) {
                idList.add(Long.parseLong(str));
            }
        } else {
            idList.add(Long.parseLong(ids));
        }
        this.baseMapper.deleteBatchIds(idList);
        return true;
    }
}
